#include "player_feature.h"

#include "../../model/player.h"
#include "../../model/core_utils.h"
#include "../../model/core_io.h"

#include <QList>
#include <QTime>

#include <stdio.h>

PlayerFeature::PlayerFeature( int _id, Engine* _engine, int _x, int _y, int _w, int _h,
                              ControllerProxy* _cProxy, MainWidget* _mw )
                                  :Feature( _id, _engine, _mw, _cProxy, _x, _y, _w, _h )
{
    InitializeFlagsAndValues();
    BuildPensAndBrushes();
    BuildWidgets();
    BuildAnimations();
}

PlayerFeature::~PlayerFeature()
{
    DeleteAnimations();
    DeletePensAndBrushes();
}

// protected functions
void PlayerFeature::Hide( void )
{
    if(!visible)
    {
        Hidden();
        return;
    }

    player->Stop();

    if(children.size() > 0)
    {
        eventCount = children.size();
        for(vector< Widget* >::iterator i=children.begin(); i!=children.end(); ++i)
        {
            (*i)->Hide();
        }
    } else
    {
        doHide();
    }
}

void PlayerFeature::doShow( void )
{
    Load();
    visible = true;
    paintEnabled = true;
    Showed();
}

void PlayerFeature::doHide( void )
{
    visible = false;
    Unload();
    Hidden();
}

void PlayerFeature::Paint( QPainter &painter )
{
    if( player->IsPlaying() && updateSlider )
    {
        int msecs = player->GetTime();
        playerSlider->SetPosition( ( float )msecs / song->length );

        if( player->segmentPlaying != -1 )
        {
            PracticeSegment* curSeg = &( song->segments[ player->segmentPlaying ] );
            int segOffset = msecs - curSeg->start;
            sSlider->SetPosition( ( float )segOffset / ( curSeg->end - curSeg->start ) );
        }
    }
}

// private functions ---------------------------------------------------

// AnimationObserver implementation
void PlayerFeature::OnPause( Animation* a )
{
    ;
}

void PlayerFeature::OnStop( Animation* a )
{
    ;
}

void PlayerFeature::OnEnd( Animation* a )
{
    ;
}

void PlayerFeature::OnPlay( Animation* a )
{
    ;
}

// PlayerListener implementation
void PlayerFeature::OnSegmentChange( int newSegment )
{
    if( newSegment == -1 )
    {
        DisableWidgets();
    }
    else
    {
        PracticeSegment* ps = &( song->segments[ newSegment ] );
        sInPlay->SetText( ps->name );
        sEnabled->SetChecked( ps->enabled, false );

        sStart->SetText( CoreUtils::GetTimePosition( ps->start ) );
        sEnd->SetText( CoreUtils::GetTimePosition( ps->end ) );
        sLength->SetText( CoreUtils::GetTimePosition( ps->end - ps->start ) );
        QString speedString = CoreUtils::GetSpeedPerc( ps->tempo );
        sSpeed->SetText( speedString );
        pSpeed->SetText( speedString );
        sPitch->SetText( CoreUtils::GetPitchString( ps->pitch ) );

        float sPos = ps->start / ( float )song->length;
        float ePos = ps->end / ( float ) song->length;
        playerSlider->Highlight( sPos, ePos );

        sSpeedSlider->SetPosition( ps->tempo/3.0 );
        sPitchSlider->SetPosition( ( ps->pitch + 12 ) / 24.0 );
        sLoopBox->SetChecked( ps->active, false );
    }
}

// SliderListener implementation
void PlayerFeature::OnPosChanged( Slider* sender, double newPos )
{
    int seg = player->segmentPlaying;
    if( seg == -1 ) return;
    PracticeSegment* ps = &( song->segments[ seg ] );

    if( sender == sSlider ) // segment slider
    {
        int time = ( ps->end - ps->start ) * newPos;
        stZZZLabel->SetText( QString::number( time % 1000 ) );
        QTime t = QTime().addMSecs( time );
        stMainTime->SetText( t.toString( "mm:ss" ) );
    }
    else if( sender == playerSlider )
    {
        int time = song->length * newPos;
        pZZZTime->SetText( QString::number( time % 1000 ) );
        QTime t = QTime().addMSecs( time );
        pTime->SetText( t.toString( "mm:ss" ) );
    }
    else if( sender == sSpeedSlider )
    {
        QString speed_string = CoreUtils::GetSpeedPerc( newPos * 3 );
        sSpeed->SetText( speed_string );
        pSpeed->SetText( speed_string );
    }
    else if( sender == sPitchSlider )
    {
        sPitch->SetText( CoreUtils::GetPitchString( newPos * 24 - 12 ) );
    }
}

void PlayerFeature::OnClickOrOnEndDrag( Slider* sender, double newPos )
{
    if( sender == playerSlider )
    {
        player->SetTime( newPos * song->length );
        updateSlider = true;
    }
    else if( sender == sSlider || sender == sSpeedSlider )
    {
        if( player->segmentPlaying == -1 )
        {
            updateSlider = true;
            return;
        }
        PracticeSegment* ps = &( song->segments[ player->segmentPlaying ] );

        if( sender == sSlider )
        {
            int offset = ( ps->end - ps->start ) * newPos;
            player->SetTime( ps->start + offset );
            updateSlider = true;
        }
        else
        {
            float newTempo = newPos * 3;
            sSpeed->SetText( CoreUtils::GetSpeedPerc( newTempo ) );
            ps->tempo = newTempo;
            player->Synchronize();
        }
    }
    else if( sender == sPitchSlider )
    {
        int newPitch = newPos * 24 - 12;
        sPitch->SetText( CoreUtils::GetPitchString( newPitch ) );

        if( player->segmentPlaying == -1 )
        {
            return;
        }
        PracticeSegment* ps = &( song->segments[ player->segmentPlaying ] );
        ps->pitch = newPitch;
        player->Synchronize();
    }
}

void PlayerFeature::OnStartDrag( Slider* slider )
{
    if( slider == sSlider || slider == playerSlider )
    {
        updateSlider = false;
    }
}

// PlayerControlsListener implementation
void PlayerFeature::OnControlClick( PlayerControls* sender, int controlId )
{
    if( controlId == PlayerControls::CTRL_PLAY )
    {
        player->Play();
        player->SetVolume( controls->volPos );
    }
    else if( controlId == PlayerControls::CTRL_PAUSE )
    {
        player->Pause();
    }
    else if( controlId == PlayerControls::CTRL_STOP )
    {
        player->Stop();
        playerSlider->SetPosition( 0.0 );
        sSlider->SetPosition( 0.0 );
    }
    else if( controlId == PlayerControls::CTRL_PREV_SEGMENT )
    {
        player->GoToPreviousSegment();
    }
    else
    {
        player->GoToNextSegment();
    }
}

void PlayerFeature::OnVolumeChange( PlayerControls* sender, float vol )
{
    player->SetVolume( vol );
}

// CheckBoxListener implementation
void PlayerFeature::OnCheckChange( CheckBox* sender, bool checked )
{
    int seg = player->segmentPlaying;
    bool ok = ( seg != -1 );

    if( sender == sEnabled && ok )
    { 
        song->segments[ seg ].enabled = checked;
        player->Synchronize();
    }
    else if( sender == sLoopBox && ok )
    {
        song->segments[ seg ].active = checked;
    }
    else if( sender == lEnabled )
    {
        int lp = loopsList->GetSelectedIndex();
        if( lp == -1 ) return;
        song->loops[ lp ].active = checked;
    }
}

// ClickableLabelListener implementation
void PlayerFeature::OnClick( ClickableLabel* sender )
{
    int seg = player->segmentPlaying;
    bool validState = ( seg != -1 );

    if( sender == sEnableAll && validState )
    {
        for( int i=0; i<song->segments.size(); i++ )
        {
            song->segments[i].enabled = true;
        }
        sEnabled->SetChecked( true, false );
        player->Synchronize();
    }
    else if( sender == sDisableAll && validState )
    {
        for( int i=0; i<song->segments.size(); i++ )
        {
            song->segments[i].enabled = false;
        }
        sEnabled->SetChecked( false, false );
        player->Synchronize();
    }
    else if( sender == sEdit )
    {
        cProxy->postOpenAction = 1;     // when the edit feature is loaded, this post action opens the
        // practice segment editor
        cProxy->UnloadRequest( ControllerProxy::EDIT_SONG_FEATURE );
    }
    else if( sender == sSave || sender == lSave )
    {
        if( song->mpsFileName == "unknown" )
        {
            // i must save the song
            cProxy->saveSong = true;
            cProxy->prevFeatureId = ControllerProxy::PLAYER_FEATURE;
            cProxy->UnloadRequest( ControllerProxy::SAVE_FILE_DIALOG_FEATURE );
        }
        else
        {
            CoreIO::SaveSong( song->mpsFileName, song );
        }
    }
    else if( sender == lEnableAll || sender == lDisableAll )
    {
        bool set = ( sender == lEnableAll );
        for( int i=0; i<song->loops.size(); i++ )
        {
            song->loops[i].active = set;
        }
        lEnabled->SetChecked( set, false );
    }
    else if( sender == lEdit )
    {
        cProxy->postOpenAction = 2;
        cProxy->UnloadRequest( ControllerProxy::EDIT_SONG_FEATURE );
    }
}

// ListListener implementation
void PlayerFeature::OnSelect(List* sender, int index)
{
    if( index == -1 ) return;

    Loop* l = &( song->loops[ index ] );
    lName->SetText( l->name );
    lStart->SetText( CoreUtils::GetTimePosition( l->start ) );
    lEnd->SetText( CoreUtils::GetTimePosition( l->end ) );
    lEnabled->SetChecked( l->active, false );

    float f_start = ( float )l->start / song->length;
    float f_end = ( float )l->end / song->length;
    lSlider->Highlight( f_start, f_end );
}

void PlayerFeature::OnDoubleClick(List* sender, int index)
{
    ;
}

// others
void PlayerFeature::InitializeFlagsAndValues( void )
{
    updateSlider = true;
}

void PlayerFeature::BuildPensAndBrushes( void )
{
    invisibleBrush = new QBrush( QColor( 0, 0, 0, 0 ), Qt::NoBrush );
}

void PlayerFeature::DeletePensAndBrushes( void )
{
    delete invisibleBrush;
}

void PlayerFeature::BuildWidgets( void )
{
    QFont normalFont( "Palatino", 11 );
    QFont boldFont( "Palatino", 11, QFont::Bold );

    // song info frame
    songInfoFrame = new GuiFrame( this, engine, "Song Info", 0, 0, w, 65 );

    songNameFixedLabel = new Label( songInfoFrame, engine, "Song Name:", 10, 25, 100, 20 );
    songNameFixedLabel->SetFont( boldFont );
    songInfoFrame->AddChild( songNameFixedLabel );

    int tmp_x = songNameFixedLabel->GetX() + songNameFixedLabel->GetTextWidth() - 30;
    songNameLabel = new CoolLabel( songInfoFrame, engine, "", tmp_x, 25, w - tmp_x, 20 );
    songNameLabel->SetFont( normalFont );
    songInfoFrame->AddChild( songNameLabel );

    songLengthFixedLabel = new Label( songInfoFrame, engine, "Song Length:", 10, 50, 150, 20 );
    songLengthFixedLabel->SetFont( boldFont );
    songInfoFrame->AddChild( songLengthFixedLabel );

    tmp_x = songLengthFixedLabel->GetX() + songLengthFixedLabel->GetTextWidth() - 30;
    songLengthLabel = new CoolLabel( songInfoFrame, engine, "", tmp_x, 50, w - tmp_x, 20 );
    songLengthLabel->SetFont( normalFont );
    songInfoFrame->AddChild( songLengthLabel );

    AddChild( songInfoFrame );

    // segments frames
    segmentsFrame = new GuiFrame( this, engine, "Practice Segments", 0, 90, w, 210 );

    // segment info
    segmentInfoFrame = new GuiFrame( segmentsFrame, engine, "Playing Info", 10, 25,
                                     segmentsFrame->GetWidth() / 5 * 4,
                                     segmentsFrame->GetHeight() - 40 );

    sFixedInPlay = new Label( segmentInfoFrame, engine, "In play:", 10, 25, 60, 20 );
    sFixedInPlay->SetFont( boldFont );
    segmentInfoFrame->AddChild( sFixedInPlay );

    tmp_x = sFixedInPlay->GetTextWidth() - 8;
    sInPlay = new CoolLabel( segmentInfoFrame, engine, "", tmp_x, 25,
                             segmentInfoFrame->GetWidth() - tmp_x - 200, 20 );
    sInPlay->SetFont( normalFont );
    segmentInfoFrame->AddChild( sInPlay );

    tmp_x = segmentInfoFrame->GetWidth() - 250;
    sEnabled = new CheckBox( segmentInfoFrame, engine, "Enabled", tmp_x, 25, 100, 20 );
    sEnabled->SetFont( normalFont );
    sEnabled->AddCheckBoxListener( this );
    segmentInfoFrame->AddChild( sEnabled );

    sFixedStart = new Label( segmentInfoFrame, engine, "Start:", 10, 50, 70, 20 );
    sFixedStart->SetFont( boldFont );
    segmentInfoFrame->AddChild( sFixedStart );

    tmp_x = sFixedStart->GetTextWidth();
    sStart = new CoolLabel( segmentInfoFrame, engine, "", tmp_x, 50, 100, 20 );
    sStart->SetFont( normalFont );
    segmentInfoFrame->AddChild( sStart );

    tmp_x = 110 + sFixedStart->GetTextWidth();
    sFixedEnd = new Label( segmentInfoFrame, engine, "End:", tmp_x, 50, 50, 20 );
    sFixedEnd->SetFont( boldFont );
    segmentInfoFrame->AddChild( sFixedEnd );

    tmp_x += sFixedEnd->GetTextWidth() - 10;
    sEnd = new CoolLabel( segmentInfoFrame, engine, "", tmp_x, 50, 100, 20 );
    sEnd->SetFont( normalFont );
    segmentInfoFrame->AddChild( sEnd );

    tmp_x += 110;
    sFixedLength = new Label( segmentInfoFrame, engine, "Length:", tmp_x, 50, 60, 20 );
    sFixedLength->SetFont( boldFont );
    segmentInfoFrame->AddChild( sFixedLength );

    tmp_x += sFixedLength->GetTextWidth() - 10;
    sLength = new CoolLabel( segmentInfoFrame, engine, "", tmp_x, 50, 100, 20 );
    sLength->SetFont( normalFont );
    segmentInfoFrame->AddChild( sLength );

    sSlider = new Slider( segmentInfoFrame, engine, 10, 75,
                          segmentInfoFrame->GetWidth() - 100, 28 );
    sSlider->AddSliderListener( this );
    segmentInfoFrame->AddChild( sSlider );

    tmp_x = 10 + sSlider->GetWidth() + 10;
    sTimeFrame = new GuiFrame( segmentInfoFrame, engine, "", tmp_x, 55, 70, 40 );

    stMainTime = new Label( sTimeFrame, engine, "", 8, 10, 54, 30, Label::Right );
    stMainTime->SetFont( QFont( "Palatino", 16 ) );
    sTimeFrame->AddChild( stMainTime );

    stZZZLabel = new Label( sTimeFrame, engine, "", 8, 35, 54, 20, Label::Right );
    stZZZLabel->SetFont( QFont( "Palatino", 9 ) );
    sTimeFrame->AddChild( stZZZLabel );

    segmentInfoFrame->AddChild( sTimeFrame );

    sFixedSpeed = new Label( segmentInfoFrame, engine, "Speed:", 10, 114, 60, 20 );
    sFixedSpeed->SetFont( boldFont );
    segmentInfoFrame->AddChild( sFixedSpeed );

    tmp_x = sFixedSpeed->GetTextWidth() - 17;
    sSpeed = new CoolLabel( segmentInfoFrame, engine, "", tmp_x, 114,
                            segmentInfoFrame->GetWidth() - tmp_x, 20 );
    sSpeed->SetFont( normalFont );
    segmentInfoFrame->AddChild( sSpeed );

    tmp_x += 95;
    sSpeedSlider = new Slider( segmentInfoFrame, engine, tmp_x, 110,
                               sSlider->GetX() + sSlider->GetWidth() - tmp_x, 28 );
    sSpeedSlider->AddSliderListener( this );
    segmentInfoFrame->AddChild( sSpeedSlider );

    sFixedPitch = new Label( segmentInfoFrame, engine, "Pitch:", 10, 148, 60, 20 );
    sFixedPitch->SetFont( boldFont );
    segmentInfoFrame->AddChild( sFixedPitch );

    tmp_x = sFixedPitch->GetTextWidth() - 17;
    sPitch = new CoolLabel( segmentInfoFrame, engine, "", tmp_x, 148,
                            segmentInfoFrame->GetWidth() - tmp_x, 20 );
    sPitch->SetFont( normalFont );
    segmentInfoFrame->AddChild( sPitch );

    tmp_x += 145;
    sPitchSlider = new Slider( segmentInfoFrame, engine, tmp_x, 144,
                               sSpeedSlider->GetX() + sSpeedSlider->GetWidth() - tmp_x, 28 );
    sPitchSlider->AddSliderListener( this );
    segmentInfoFrame->AddChild( sPitchSlider );

    tmp_x = sTimeFrame->GetX() + sTimeFrame->GetWidth() - 115;
    sLoopBox = new CheckBox( segmentInfoFrame, engine, "Loop segment", tmp_x,
                             sEnabled->GetY(), 115, 20 );
    sLoopBox->SetFont( normalFont );
    sLoopBox->AddCheckBoxListener( this );
    segmentInfoFrame->AddChild( sLoopBox );

    segmentsFrame->AddChild( segmentInfoFrame );

    // segments actions
    tmp_x = segmentInfoFrame->GetX() + segmentInfoFrame->GetWidth() + 10;
    segmentsActionFrame = new GuiFrame( segmentsFrame, engine, "Actions",
                                        tmp_x, 25, w - tmp_x - 10, segmentInfoFrame->GetHeight() );

    sEnableAll = new ClickableLabel( segmentsActionFrame, engine, "Enable All", 10, 25, 100, 20 );
    sEnableAll->SetFont( normalFont );
    sEnableAll->AddClickableListener( this );
    segmentsActionFrame->AddChild( sEnableAll );

    sDisableAll = new ClickableLabel( segmentsActionFrame, engine, "Disable All", 10, 50, 100, 20 );
    sDisableAll->SetFont( normalFont );
    sDisableAll->AddClickableListener( this );
    segmentsActionFrame->AddChild( sDisableAll );

    sEdit = new ClickableLabel( segmentsActionFrame, engine, "Edit", 10, 75, 100, 20 );
    sEdit->SetFont( normalFont );
    sEdit->AddClickableListener( this );
    segmentsActionFrame->AddChild( sEdit );

    sSave = new ClickableLabel( segmentsActionFrame, engine, "Save", 10, 100, 70, 20 );
    sSave->SetFont( normalFont );
    sSave->AddClickableListener( this );
    segmentsActionFrame->AddChild( sSave );

    segmentsFrame->AddChild( segmentsActionFrame );

    AddChild( segmentsFrame );

    // player frame
    playerFrame = new GuiFrame( this, engine, "Player", 0,
                                segmentsFrame->GetY() + segmentsFrame->GetHeight() + 25, w, 135 );

    playerSlider = new PSSlider( playerFrame, engine, 10, 20, w - 110, 48 );
    playerSlider->AddSliderListener( this );
    playerFrame->AddChild( playerSlider );

    controls = new PlayerControls( playerFrame, engine, 10,
                                   playerSlider->GetY() + playerSlider->GetHeight() + 20,
                                   500, 50 );
    controls->AddPlayerControlsListener( this );
    playerFrame->AddChild( controls );

    tmp_x = 10 + playerSlider->GetWidth() + 10;
    pTimeFrame = new GuiFrame( playerFrame, engine, "", tmp_x, 5,
                               playerFrame->GetWidth() - tmp_x - 10, 50 );
    pTime = new Label( pTimeFrame, engine, "", 10, 15, pTimeFrame->GetWidth() - 20, 30, Label::Right );
    pTime->SetFont( QFont( "Palatino", 18 ) );
    pTimeFrame->AddChild( pTime );

    pZZZTime = new Label( pTimeFrame, engine, "", 10, 40, pTime->GetWidth(), 20, Label::Right );
    pZZZTime->SetFont( normalFont );
    pTimeFrame->AddChild( pZZZTime );

    tmp_x = controls->GetX() + controls->GetWidth() + 55;
    int tmp_y = pTimeFrame->GetY() + pTimeFrame->GetHeight() + 10;
    pSpeedFrame = new GuiFrame( playerFrame, engine, "", tmp_x, tmp_y,
                                pTimeFrame->GetX() + pTimeFrame->GetWidth() - tmp_x,
                                playerFrame->GetHeight() - 10 - tmp_y );

    pSpeed = new Label( pSpeedFrame, engine, "100%", 55, 22, pSpeedFrame->GetWidth() - 55,
                        pSpeedFrame->GetHeight() - 25, Label::Center );
    pSpeed->SetFont( QFont( "Palatino", 28 ) );
    pSpeedFrame->AddChild( pSpeed );

    pFixedSpeed = new Label( pSpeedFrame, engine, "Speed:",
                             pSpeed->GetX() + pSpeed->GetWidth() - pSpeed->GetTextWidth() - 55,
                             pSpeed->GetY() + pSpeed->GetHeight() - 18,
                             45, 20 );
    pFixedSpeed->SetFont( normalFont );
    pSpeedFrame->AddChild( pFixedSpeed );

    playerFrame->AddChild( pSpeedFrame );
    playerFrame->AddChild( pTimeFrame );

    AddChild( playerFrame );

    tmp_y = playerFrame->GetY() + playerFrame->GetHeight() + 25;
    loopsFrame = new GuiFrame( this, engine, "Loops", 0, tmp_y, w, h - tmp_y - 10 );

    loopsList = new List( loopsFrame, engine, 10, 25, 200, loopsFrame->GetHeight() - 20, 20 );
    loopsList->AddListListener( this );
    loopsFrame->AddChild( loopsList );

    tmp_x = 220;
    lInfoFrame = new GuiFrame( loopsFrame, engine, "Info", tmp_x, loopsList->GetY(),
                               ( w - loopsList->GetWidth() - 20 ) / 4 * 3, loopsFrame->GetHeight() - 35 );

    lFixedName = new Label( lInfoFrame, engine, "Name:", 10, 25, lInfoFrame->GetWidth() - 20, 20 );
    lFixedName->SetFont( boldFont );
    lInfoFrame->AddChild( lFixedName );

    lEnabled = new CheckBox( lInfoFrame, engine, "Enabled", 10, 50, 70, 20 );
    lEnabled->SetFont( normalFont );
    lEnabled->AddCheckBoxListener( this );
    lInfoFrame->AddChild( lEnabled );

    tmp_x = lFixedName->GetTextWidth() - 20;
    lName = new CoolLabel( lInfoFrame, engine, "", tmp_x, 25, loopsFrame->GetWidth() - 20, 20 );
    lName->SetFont( normalFont );
    lInfoFrame->AddChild( lName );

    lFixedStart = new Label( lInfoFrame, engine, "Start:", 10, 75, 60, 20 );
    lFixedStart->SetFont( boldFont );
    lInfoFrame->AddChild( lFixedStart );

    tmp_x = lFixedStart->GetTextWidth();
    lStart = new CoolLabel( lInfoFrame, engine, "", tmp_x, 75, 100, 20 );
    lStart->SetFont( normalFont );
    lInfoFrame->AddChild( lStart );

    lFixedEnd = new Label( lInfoFrame, engine, "End:", lStart->GetX() + 100, 75, 50, 20 );
    lFixedEnd->SetFont( boldFont );
    lInfoFrame->AddChild( lFixedEnd );

    tmp_x = lFixedEnd->GetX() + lFixedEnd->GetTextWidth() - 10;
    lEnd = new CoolLabel( lInfoFrame, engine, "", tmp_x, 75, 100, 20 );
    lEnd->SetFont( normalFont );
    lInfoFrame->AddChild( lEnd );

    lSlider = new PSSlider( lInfoFrame, engine, 10, 100, lInfoFrame->GetWidth() - 20, 20 );
    lSlider->showBall = false;
    lSlider->showCursors = false;
    lInfoFrame->AddChild( lSlider );

    loopsFrame->AddChild( lInfoFrame );

    tmp_x = lInfoFrame->GetX() + lInfoFrame->GetWidth() + 10;
    lActionsFrame = new GuiFrame( loopsFrame, engine, "Actions", tmp_x, lInfoFrame->GetY(),
                                  w - tmp_x - 10, lInfoFrame->GetHeight() );

    lEnableAll = new ClickableLabel( lActionsFrame, engine, "Enable All", 10, 25, 100, 20 );
    lEnableAll->SetFont( normalFont );
    lEnableAll->AddClickableListener( this );
    lActionsFrame->AddChild( lEnableAll );

    lDisableAll = new ClickableLabel( lActionsFrame, engine, "Disable All", 10, 50, 100, 20 );
    lDisableAll->SetFont( normalFont );
    lDisableAll->AddClickableListener( this );
    lActionsFrame->AddChild( lDisableAll );

    lEdit = new ClickableLabel( lActionsFrame, engine, "Edit", 10, 75, 100, 20 );
    lEdit->SetFont( normalFont );
    lEdit->AddClickableListener( this );
    lActionsFrame->AddChild( lEdit );

    lSave = new ClickableLabel( lActionsFrame, engine, "Save", 10, 100, 60, 20 );
    lSave->SetFont( normalFont );
    lSave->AddClickableListener( this );
    lActionsFrame->AddChild( lSave );

    loopsFrame->AddChild( lActionsFrame );

    AddChild( loopsFrame );
}

void PlayerFeature::BuildAnimations( void )
{
    ;
}

void PlayerFeature::DeleteAnimations( void )
{
    ;
}

void PlayerFeature::Load( void )
{
    // Player initialization
    player = Player::GetInstance();
    player->SetPlaybackMode( true );
    player->Stop();
    player->AddPlayerListener( this );
    song = player->song;

    // player slider initialization
    QList< double > highlights;
    for( int i = 0; i < song->segments.size() - 1; i++ )
    {
        highlights << ( song->segments[i].end / ( float ) song->length );
    }
    playerSlider->SetHighlightPoints( highlights );
    playerSlider->SetPosition( 0.0 );
    playerSlider->Highlight( 0.0, 0.0 );
    updateSlider = true;
    controls->Init();
    player->vol = controls->volPos * 255;

    // loops list initialization
    QStringList loops;
    for( int i=0; i< song->loops.size(); i++ )
    {
        loops << song->loops[i].name;
    }
    loopsList->SetStringList( loops );

    // widgets initialization
    songNameLabel->SetText( song->songName );
    songLengthLabel->SetText( CoreUtils::GetTimePosition( song->length ) );
    DisableWidgets();
}

void PlayerFeature::Unload( void )
{
    //player->Stop();
    player->RemovePlayerListener( this );
}

void PlayerFeature::DisableWidgets( void )
{
    sInPlay->SetText( "-" );
    sEnabled->SetChecked( false, false );
    sStart->SetText( "-" );
    sEnd->SetText( "-" );
    sLength->SetText( "-" );
    sSlider->SetPosition( 0.0 );
    stMainTime->SetText( "00:00" );
    stZZZLabel->SetText( "000" );
    sSpeed->SetText( "-" );
    sSpeedSlider->SetPosition( 0.5 );
    sPitch->SetText( "-" );
    pTime->SetText( "00:00" );
    pZZZTime->SetText( "000" );
    sLoopBox->SetChecked( false, false );
    pSpeed->SetText( "-" );
    lName->SetText( "-" );
    lStart->SetText( "-" );
    lEnd->SetText( "-" );
    lSlider->Highlight( 0.0, 0.0 );
}

